package core;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

import org.apache.log4j.Logger;

import core.descriptors.WorkerDescriptor;
import core.interfaces.Discovery;
import core.manager.Manager;
import core.manager.WorkerNetwork;
import core.util.SockUtil;
import core.ui.UI;
import core.util.COREServiceRegistry;
import core.worker.Address;
import core.worker.Worker;

/**
 *
 * Implementa lo scheletro della classe CORE @see CORE. Essa rappresenta il nucleo di istanziazione, configurazione e creazione della piattaforma.
 *
 *
 * @author Vincenzo Merlo, Paolo Giuffrida, Scuderi Giovanni Luca
 */
public class COREP2P extends CORE {

    private final Logger logger = COREServiceRegistry.getLogger(COREP2P.class.toString()); //istanza logger log4j

    /**
     * Inizializza i componenti della piattaforma: Manager, Worker, WorkerDiscovery, UI e carica la configurazione dei peer dal file peeraddress.txt
     */
    @Override
    public void init() {
        if (this.getConfigFile() == null) // carica il file property di default
        {
            
        }
        logger.debug("Called init ");
        createManager();
        createWorker();
        createDiscovery();
        createUI();
        initDiscovery();
    }

    /**
     * Crea l'istanza singleton del Manager
     * @return istanza Manager
     */
    private Manager createManager() {
        logger.debug("called - createManager " + this);
        return COREServiceRegistry.getManager();
    }

    /**
     * Crea l'istanza singleton del Worker
     * @return istanza worker
     */
    private Worker createWorker() {
        logger.debug("called - createWorker " + this);
        return new Worker();
    }

    /**
     * Crea l'istanza singleton del WorkerDiscovery. Ritorna un Discovery per estensibilità
     * @return istanza Discovery @see WorkerDiscovery
     */
    private Discovery createDiscovery() {
        logger.debug("called - createDiscovery " + this);
        return COREServiceRegistry.getDiscovery();
    }
    /**
     * Crea la UI
     * @return istanza UI
     */

    private UI createUI() {
        logger.debug("called - createUI " + this);
        return new UI();
    }

    /**
     * Inizializza la Discovery. Carica la lista dei peer e li comunica al Discovery
     * La struttura del peeraddress è indirizzo:porta. Se la porta non è esplicitata nel file peeraddress.txt viene settata la porta di Default
     */
    private void initDiscovery() {
        FileReader fr = null;
        new WorkerNetwork();
        WorkerDescriptor wd;
        try {
            fr = new FileReader("peeraddress.txt");
            BufferedReader br = new BufferedReader(fr);
            String s;
            String add[];
            while ((s = br.readLine()) != null) {
                Address addr = new Address();

                add = s.split(":");
                if (add.length > 1) {
                    addr.setIP(add[0]);
                    addr.setPort(Integer.parseInt(add[1]));
                } else {
                    addr.setIP(s);
                    addr.setPort(SockUtil.portMessagesSender);
                }
                wd = new WorkerDescriptor();
                wd.setAddr(addr);
                COREServiceRegistry.getDiscovery().addWorker(wd);
            }
            fr.close();
        } catch (FileNotFoundException ex) {
            logger.error("file error" + ex.getStackTrace());
            
        } catch (IOException ex) {
            logger.error("file error" + ex.getStackTrace());
        } 

    }
}
